﻿using GamFi.Admin.API.Application.Contracts.Token.GetTokens;
using GamFi.Admin.API.Application.Exceptions;
using GamFi.Admin.API.Application.Interfaces;
using GamFi.Admin.API.Application.Resources;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;

namespace GamFi.Admin.API.Application.Features.Queries.Token.GetTokens;

/// <summary>
/// Обработчик запроса для получения списка токенов с учетом пагинации.
/// </summary>
public class GetTokensQueryHandler : IRequestHandler<GetTokensQuery, GetTokensResponse>
{
    private readonly IDbContext _dbContext;
    private readonly IStringLocalizer<ExceptionMessages> _localizer;

    /// <summary>
    /// Конструктор обработчика запроса для получения списка токенов с учетом пагинации.
    /// </summary>
    /// <param name="dbContext">Контекст базы данных.</param>
    /// <param name="localizer"></param>
    public GetTokensQueryHandler(IDbContext dbContext, IStringLocalizer<ExceptionMessages> localizer)
    {
        _dbContext = dbContext;
        _localizer = localizer;
    }

    /// <summary>
    /// Обработка запроса для получения списка токенов с учетом пагинации.
    /// </summary>
    /// <param name="request">Запрос на получение списка токенов.</param>
    /// <param name="cancellationToken">Токен для отмены операции.</param>
    /// <returns>Ответ с списком токенов.</returns>
    public async Task<GetTokensResponse> Handle(GetTokensQuery request, CancellationToken cancellationToken)
    {
        if (request is null)
            throw new RequestException(_localizer[nameof(RequestException.RequestIsEmpty)]);

        // Получение всех токенов из базы данных
        IQueryable<Domain.Entities.Token> query = _dbContext.Tokens;

        // Применение фильтра, если он предоставлен
        if (!string.IsNullOrEmpty(request.Filter))
        {
            query = query.Where(token =>
                token.Name.Contains(request.Filter) ||
                token.TokenSymbol.Contains(request.Filter) ||
                token.Id.ToString().Contains(request.Filter) ||
                token.TokenSummary.Contains(request.Filter) ||
                token.TotalRaise.ToString().Contains(request.Filter) ||
                token.TargetedRaise.ToString().Contains(request.Filter) ||
                token.ChainId.ToString().Contains(request.Filter) ||
                token.ImageId.HasValue && token.ImageId.ToString().Contains(request.Filter) ||
                token.CreatedBy.HasValue && token.CreatedBy.ToString().Contains(request.Filter));
        }

        // Применение пагинации
        var tokens = await query
            .Skip(request.PageNumber * request.PageSize)
            .Take(request.PageSize)
            .ToListAsync(cancellationToken);

        // Маппинг токенов в GetTokensResponse
        var response = new GetTokensResponse
        {
            Tokens = tokens.Select(token => new TokenDto
            {
                TokenId = token.Id,
                Name = token.Name,
                TokenPrice = token.TokenPrice,
                TokenSymbol = token.TokenSymbol,
                ChainId = token.ChainId,
                CreatedDate = token.CreatedDate,
                CreatedBy = token.CreatedBy,
                TargetedRaise = token.TargetedRaise,
                TotalRaise = token.TotalRaise,
                TokenSummary = token.TokenSummary,
                ImageId = token.ImageId
            }).ToList()
        };

        return response;
    }
}